package test.base;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.support.BindingAwareModelMap;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;

import com.cap.bts.commonfunc.common.util.UserUtil;
import com.cap.bts.framework.common.util.ApplicationContextUtil;
import com.cap.bts.framework.usermgnt.domain.User;



/**
 * @author annson
 * 
 */
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath*:spring-context.xml","classpath*:spring-dispatcher.xml" })
@Transactional
@TransactionConfiguration(transactionManager="txManager", defaultRollback = true) 
public class BaseJunit4 {
	
	private static HandlerMapping handlerMapping;
	private static HandlerAdapter handlerAdapter;

  // 模拟request,response  
    public MockHttpServletRequest request;  
    public MockHttpServletResponse response; 
    public Model model;
    
    // 执行测试方法之前初始化模拟request,response  
    @Before    
    public void setUp(){    
        System.out.println("@@@@@@@@@@@@@@@@@@@Before unit");
    	initParam();
    }   
    
    public Long getCurrentDealerId(){
    	return 123456L;
    }
    
    public void initParam(){
    	
    	request = new MockHttpServletRequest();      
        request.setCharacterEncoding("UTF-8");   
        request.addHeader("USER-AGENT", "FIREFOX");
        response = new MockHttpServletResponse();
        model = new BindingAwareModelMap();
    	
		RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
		
		User user = new User();
        user.setId(0L);
        user.setDealerId(getCurrentDealerId());
        
        UserUtil.setMarsCurrentUser(user);        
        request.getSession().setAttribute("userSession", user);
        request.getSession().setAttribute("FROM_MARS_FLAG", true);
        
        if(handlerMapping == null){
        	System.out.println("init context.....");
         	ApplicationContext context = ApplicationContextUtil.getApplicationContext();
    		
    		MockServletContext msc = new MockServletContext();
    		
    		msc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context);
    		handlerMapping = (HandlerMapping) context.getBean(DefaultAnnotationHandlerMapping.class);
    		handlerAdapter = (HandlerAdapter) context
    				.getBean(context.getBeanNamesForType(AnnotationMethodHandlerAdapter.class)[0]);
        }
	}
	
	/**
	 * 执行request对象请求的action
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ModelAndView excuteAction(HttpServletRequest request, HttpServletResponse response) throws Exception {

		HandlerExecutionChain chain = handlerMapping.getHandler(request);
		final ModelAndView model = handlerAdapter.handle(request, response, chain.getHandler());
		return model;
	}
}